commonlibsse_ng\re\h/
hkBaseTypes.rs

1/// Alias for a 16-bit unsigned integer used as an object index in Havok.
2pub type hkObjectIndex = u16;
3
4/// Alias for a 32-bit float used as time in Havok.
5pub type hkTime = f32;
6
7/// Enumeration representing the result of a Havok operation.
8#[commonlibsse_ng_derive_internal::ffi_enum]
9#[repr(i32)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub enum hkResult {
12    Success = 0,
13    Failure = 1,
14}
15
16/// Represents a 16-bit half-precision float with 7-bit precision in the Havok system.
17///
18/// This is a wrapper around a 16-bit integer that stores a compressed float value.
19///
20/// # Memory Layout:
21/// - `_value`: 16-bit integer storing the half-precision float (0x00 - 0x01)
22#[repr(C)]
23#[derive(Debug, Clone, Copy, PartialEq)]
24pub struct hkHalf {
25    /// The underlying 16-bit integer storing the half-precision float.
26    /// - Offset: 0x00
27    _value: i16,
28}
29
30// Compile-time memory layout verification
31const _: () = {
32    assert!(core::mem::offset_of!(hkHalf, _value) == 0x0);
33    assert!(core::mem::size_of::<hkHalf>() == 0x2);
34};
35
36impl hkHalf {
37    /// Creates a new `hkHalf` with a default value of 0.0.
38    #[inline]
39    pub const fn new() -> Self {
40        Self { _value: 0 }
41    }
42
43    /// Creates a new `hkHalf` from a 32-bit float.
44    #[inline]
45    pub const fn from_f32(a_val: f32) -> Self {
46        let mut half = Self::new();
47        half.set_f32(a_val);
48        half
49    }
50
51    /// Sets the internal half-precision value from a 32-bit float.
52    #[inline]
53    const fn set_f32(&mut self, a_val: f32) {
54        // Simplified conversion; actual half-precision float conversion would use IEEE 754 rules
55        let bits = a_val.to_bits();
56        let sign = (bits >> 31) as i16;
57        let exp = ((bits >> 23) & 0xFF) as i16 - 127 + 15; // Adjust bias: 127 (f32) to 15 (f16)
58        let mantissa = (bits & 0x7FFFFF) >> 13; // Take top 10 bits of 23-bit mantissa
59        if exp <= 0 {
60            self._value = 0; // Underflow to zero
61        } else if exp > 31 {
62            self._value = (sign << 15) | 0x7C00; // Infinity
63        } else {
64            self._value = (sign << 15) | (exp << 10) | mantissa as i16;
65        }
66    }
67
68    /// Gets the 32-bit float value from this `hkHalf`.
69    #[inline]
70    fn to_f32(self) -> f32 {
71        // Simplified conversion; actual half-precision float conversion would use IEEE 754 rules
72        let sign = (self._value >> 15) & 0x1;
73        let exp = ((self._value >> 10) & 0x1F) as u32;
74        let mantissa = (self._value & 0x3FF) as u32;
75        if exp == 0 {
76            if mantissa == 0 {
77                0.0 // Zero
78            } else {
79                // Subnormal number
80                f32::from_bits(((sign as u32) << 31) | (mantissa << 13))
81                    * 2.0_f32.powi(-14 - 127 + 15)
82            }
83        } else if exp == 0x1F {
84            if mantissa == 0 {
85                if sign == 0 { f32::INFINITY } else { f32::NEG_INFINITY } // Infinity
86            } else {
87                f32::NAN // NaN
88            }
89        } else {
90            f32::from_bits(((sign as u32) << 31) | ((exp + 127 - 15) << 23) | (mantissa << 13))
91        }
92    }
93}
94
95impl Default for hkHalf {
96    #[inline]
97    fn default() -> Self {
98        Self::new()
99    }
100}
101
102impl From<f32> for hkHalf {
103    #[inline]
104    fn from(a_val: f32) -> Self {
105        Self::from_f32(a_val)
106    }
107}
108
109impl From<hkHalf> for f32 {
110    #[inline]
111    fn from(val: hkHalf) -> Self {
112        val.to_f32()
113    }
114}
115
116/// Represents an 8-bit unsigned float in the Havok system.
117///
118/// This is an index into a lookup table for values ranging from 0.01 to 1,000,000.0.
119///
120/// # Memory Layout:
121/// - `value`: 8-bit unsigned integer (0x00)
122#[repr(C)]
123#[derive(Debug, Default, Clone, Copy, PartialEq)]
124pub struct hkUFloat8 {
125    /// The 8-bit index into a lookup table.
126    /// - Offset: 0x00
127    pub value: u8,
128}
129
130// Compile-time memory layout verification
131const _: () = {
132    assert!(core::mem::offset_of!(hkUFloat8, value) == 0x0);
133    assert!(core::mem::size_of::<hkUFloat8>() == 0x1);
134};